home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Simulation / PDP-8 Simulator / Source Code / Assembler / CodeHelp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-13  |  4.5 KB  |  247 lines  |  [TEXT/KAHL]

  1. /************************************************************
  2. *
  3. *
  4. *    Unit containing instruction code helping routines.
  5. *
  6. *    by Adrian Bool in cooperation with Graham Cox.
  7. *
  8. *    copyright © phantasm coding 1992.
  9. *
  10. *
  11. ************************************************************/
  12.  
  13. #include "Global.h"
  14. #include "Code.h"
  15.  
  16. #include "CodeHelp.proto.h"
  17.  
  18. opcode getOpcode(char *theText)
  19.     {
  20.     short x;
  21.     short found;
  22.     
  23.     found = false;
  24.     
  25.     for (x=1 ; x <= noOfOpcodes ; x++) 
  26.     if (strcmp(theText,pdp8[x].mnemonic) == 0) 
  27.         {
  28.         found = true;
  29.         break;
  30.         } 
  31.     
  32.     if (found)
  33.         return(x);
  34.     else
  35.         {
  36.         AsmError = NoSuchOpcode;
  37.         return(0);
  38.         }
  39.     }
  40.     
  41.  
  42. void makeMemoryInstruction(opcode theInstruction,rBlock theResult,pHandle theProgram)
  43.     {
  44.     short theAddress;
  45.     str255 theOperand;
  46.     
  47.     theResult[0] = pdp8[theInstruction].iNumber << 9;    /* enter instuction code in top 4 bits */
  48.     getSection(theProgram,theOperand);
  49.     if (!AsmError)
  50.         {
  51.         theAddress = evaluateAddress(theProgram,theOperand);
  52.         theResult[0] |= theAddress;                        /* and put the address in bottom 7 bits */
  53.         }
  54.     }
  55.  
  56.  
  57. addressType evaluateAddress(pHandle theProgram , char *theSegment)
  58.     {
  59.     char x;
  60.     str255 aSeection;
  61.     addressType theValue,
  62.                 theAddress;
  63.                 
  64.     theAddress = 0;
  65.             
  66.     if (theSegment[0] == '*') 
  67.         {
  68.         theAddress |= (1 << 8);                    /* set indirection bit */
  69.         theSegment++;
  70.         }
  71.     
  72.     theValue = evaluateValue(theProgram,theSegment);
  73.     
  74.     if (theValue < 128)
  75.         { /* its zero page */
  76.         theAddress |= (theValue & 127);          /* allow only bottom 6 bits through */
  77.         }
  78.     else
  79.         {    
  80.         if (pageOf(theValue) == thisPage(theProgram)) 
  81.             {
  82.             theAddress |= (theValue & 127);
  83.             theAddress |= (1 << 7);                    /* set present-page bit */
  84.             }
  85.         else
  86.             AsmError = AddressOutOfRange;
  87.         }
  88.         
  89.     return(theAddress);
  90.     }
  91.     
  92. wordType evaluateValue(pHandle theProgram , char *theSegment)
  93.     {
  94.     str255 thePart;
  95.     short partPosition;
  96.     long total,value;
  97.     operator theOperator;
  98.     
  99.     partPosition = 0;
  100.     
  101.     do
  102.         {
  103.         theOperator = getPart(theSegment,&partPosition,thePart);
  104.         if (thePart[0] != '\0')
  105.             {
  106.             value = evaluatePart(theProgram,thePart);
  107.             if (!AsmError)
  108.                 {
  109.                 switch (theOperator)
  110.                     {
  111.                     case None            : total = value; 
  112.                                           break;
  113.                     case Add            : total += value;
  114.                                           break;
  115.                     case Subtract          : total -= value;
  116.                                           break;
  117.                     case RevSubtract     : total = value - total;
  118.                                           break;
  119.                     case Multiply         : total *= value;
  120.                                           break;
  121.                     case Divide            : 
  122.                         if (value > 0)
  123.                             total /= value;
  124.                         else
  125.                             AsmError = DivisionByZero;
  126.                         break;
  127.                     case RevDivide        :
  128.                         if (total > 0)
  129.                             total = value / total;
  130.                         else
  131.                             AsmError = DivisionByZero;
  132.                         break;
  133.                     case And            : total &= value;
  134.                                           break;
  135.                     case Or             : total |= value;
  136.                                           break;
  137.                     case Not            : total = (!value);
  138.                                           break;
  139.                     }
  140.                 }
  141.             }
  142.         }
  143.     while ((theOperator != End) && !AsmError);
  144.     
  145.     if ((total > 4095) && !AsmError)
  146.         {
  147.         AsmError = BadNumber;
  148.         return(0);
  149.         }
  150.     else
  151.         return(total);
  152.         
  153.     return(0);
  154.     }
  155.     
  156.     
  157. wordType evaluatePart(pHandle theProgram , char *thePart)
  158.     {
  159.     wordType    theValue;
  160.     
  161.      if (isalpha(thePart[0]))
  162.          theValue = getLabelValue((*theProgram)->labelHeader,thePart);
  163.     else
  164.         {
  165.         if (isdigit(thePart[0]))
  166.             theValue = atoi(thePart);
  167.         else
  168.             {
  169.             if (thePart[0] == '%')
  170.                 theValue = otoi(&thePart[1]);
  171.             else
  172.                 {
  173.                 if (thePart[0] == '$')
  174.                     theValue = htoi(&thePart[1]);
  175.                 else
  176.                     AsmError = SyntaxError;
  177.                 }
  178.             }
  179.         }
  180.     return(theValue);
  181.     }
  182.  
  183.  
  184. wordType htoi(char *theText)
  185.     {
  186.     long total;
  187.     short chValue;
  188.     short noOfDigits,x;
  189.     
  190.     total = 0;
  191.     noOfDigits = strlen(theText);
  192.     for (x = 0 ; x < noOfDigits ; x++)
  193.         {
  194.         if (isdigit(theText[x]))
  195.             chValue = theText[x] - 0x30;
  196.         if (isalpha(theText[x]))
  197.             {
  198.             if (theText[x] <= 0x66)
  199.                 chValue = theText[x] - 0x57;
  200.             else
  201.                 {
  202.                 AsmError = BadHex;
  203.                 return(0);
  204.                 }
  205.             }
  206.         total = (total *16) + chValue;
  207.         }        
  208.     return(total);
  209.     }
  210.     
  211. wordType otoi(char *theText)
  212.     {
  213.     long total;
  214.     short chValue;
  215.     short noOfDigits,x;
  216.     
  217.     total = 0;
  218.     noOfDigits = strlen(theText);
  219.     for (x = 0 ; x < noOfDigits ; x++)
  220.         {
  221.         if (isdigit(theText[x]))
  222.             {
  223.             if (theText[x] < 0x38)
  224.                 chValue = theText[x] - 0x30;
  225.             else
  226.                 AsmError = BadOct;
  227.             }
  228.         total = (total *8) + chValue;
  229.         }        
  230.     return(total);
  231.     }
  232.         
  233. short thisPage(pHandle theProgram)
  234.     {
  235.     return(pageOf((*(*theProgram)->objectCode)->address));
  236.     }
  237.  
  238.  
  239. short pageOf(addressType anAddress)
  240.     {
  241.     short page;
  242.     
  243.     page = anAddress & 0xf80;                   /* mask out all except page info */
  244.     page >>= 7;                                  /* move to begining of the integer */
  245.     return(page);
  246.     }
  247.